package top.yangbuyi.system.config;

import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * description:  杨不易网站 :www.yangbuyi.top
 * program:  yangbuyi-erp-2020
 * ClassName:  RedisConfig
 * create:  2020-04-21 14:19
 *
 * @author: yangbuyi
 * @since： JDK1.8
 **/
// 声明配置文件
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
      
      /**
       * 定义了  RedisCacheConfig   则  应该有个东西 吧CacheProperties  注入失败了
       */
      
      /**
       * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
       *
       * @param
       * @return
       */
      @Bean
      public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);

//        // 使用Jackson2JsonRedisSerialize 替换默认序列化
//        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//
//        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
            
            // 设置value的序列化规则和 key的序列化规则
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
//        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
//        redisTemplate.afterPropertiesSet();
            return redisTemplate;
      }
      
      
      @Bean
      public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
            CacheProperties.Redis redisProperties = cacheProperties.getRedis();
            
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            // 使用Jackson2JsonRedisSerialize 替换默认序列化
//            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//
//            ObjectMapper objectMapper = new ObjectMapper();
//            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//            objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//            jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//		 + Duration.ofSeconds()
            // 设置默认配置策略
//            redisTemplate.setKeySerializer(new StringRedisSerializer());
//            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            
            RedisCacheConfiguration config = RedisCacheConfiguration
                  .defaultCacheConfig()
                  .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                  .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new GenericJackson2JsonRedisSerializer()));
            
            // 序列化策略
            // 如需修改  new GenericJackson2JsonRedisSerializer() 修改这个即刻
//            config = config.serializeValuesWith(RedisSerializationContext.SerializationPair
//                  .fromSerializer(new GenericJackson2JsonRedisSerializer()));
            
            // 定义缓存过期时间/
//            Integer secode = 7 * 24 * 6000;
            
            if (redisProperties.getTimeToLive() != null) {
                  System.out.println(redisProperties.getTimeToLive());
                  config = config.entryTtl(redisProperties.getTimeToLive());
            }
            if (redisProperties.getKeyPrefix() != null) {
                  config = config.prefixKeysWith(redisProperties.getKeyPrefix());
            }
            if (!redisProperties.isCacheNullValues()) {
                  config = config.disableCachingNullValues();
            }
            if (!redisProperties.isUseKeyPrefix()) {
                  config = config.disableKeyPrefix();
            }
            return config;
            
      }
      
      
     
      
      /**
       * 对hash类型的数据操作
       *
       * @param redisTemplate
       * @return
       */
      @Bean
      public HashOperations<String, String, Object> hashOperations(RedisTemplate redisTemplate) {
            return redisTemplate.opsForHash();
      }
      
      /**
       * 对redis字符串类型数据操作
       *
       * @param redisTemplate
       * @return
       */
      @Bean
      public ValueOperations<String, Object> valueOperations(RedisTemplate redisTemplate) {
            return redisTemplate.opsForValue();
      }
      
      /**
       * 对链表类型的数据操作
       *
       * @param redisTemplate
       * @return
       */
      @Bean
      public ListOperations<String, Object> listOperations(RedisTemplate redisTemplate) {
            return redisTemplate.opsForList();
      }
      
      /**
       * 对无序集合类型的数据操作
       *
       * @param redisTemplate
       * @return
       */
      @Bean
      public SetOperations<String, Object> setOperations(RedisTemplate redisTemplate) {
            return redisTemplate.opsForSet();
      }
      
      /**
       * 对有序集合类型的数据操作
       *
       * @param redisTemplate
       * @return
       */
      @Bean
      public ZSetOperations<String, Object> zSetOperations(RedisTemplate redisTemplate) {
            return redisTemplate.opsForZSet();
      }
      
      
      
}